/*
 * @Author: yangni 920556271@qq.com
 * @Date: 2023-08-29 14:36:07
 * @LastEditors: yangni 920556271@qq.com
 * @LastEditTime: 2024-01-03 09:55:28
 * @FilePath: /yt-devops/lib/utils/socket/use_subscribe.dart
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import 'dart:async';

import 'package:yt_devops/components/log_utils.dart';
import 'package:yt_devops/utils/socket/use_socket.dart';

/// 开启websocket 订阅和监听
///
/// 返回监听到的数据的流

class UseSubsribe {
  Map<String, dynamic> datas = {};
  StreamController<Map<String, dynamic>> controller =
      StreamController<Map<String, dynamic>>.broadcast();

  List<int> idList = [];

  MessageEventType? eventType;

  final bool isContainDeviceId; //是否返回多设备的订阅,如果是则返回res的原始数据
  bool isMultipleDevice; //是否返回多设备的订阅,如果是则返回res的原始数据
  UseSubsribe({this.isContainDeviceId = false, this.isMultipleDevice = false});

  ///
  /// [ids]  设备id集合
  /// [open] 是否开启监听
  /// [type] 监听类型
  /// [isDeviceIdAsKey] 为 true 时 , 则map 带有device id 例如 {
  ///   ```  deviceId: 23578,
  ///        networkStatus:0
  ///  ```
  StreamController<Map<String, dynamic>> start(
    List<int> ids,
    bool open, {
    MessageEventType type = MessageEventType.deviceRealData,
  }) {
    idList = ids;
    eventType = type;
    UseSocket.getInstance()
      ?..reconnect()
      ..sendMessage(RequestMessageType(
          type: type,
          data: RequestMessageBody(
              command: open
                  ? RequestCommandEnum.subscribe
                  : RequestCommandEnum.unsubscribe,
              params: ids.map((e) => {'device': e}).toList())))
      ..addReceivedMessageCallback(dealtMeesageCallback);
    return controller;
  }

  dealtMeesageCallback(data) {
    if (eventType?.value == data['type'] &&
        idList.any((item) => item == data['data']['deviceId'])) {
      var res = data['data'];

      Map<String, dynamic> obj = {};

      if (isContainDeviceId) {
        res['keyValues'].forEach((item) => {
              obj.putIfAbsent(
                  "${item['key']}-${res['deviceId']}", () => item['value'])
            });
      } else if (isMultipleDevice) {
        var deviceId = res['deviceId'].toString();
        Map<String, dynamic> deviceMap = obj[deviceId] ?? {};
        res['keyValues']
            .forEach((item) => deviceMap.addAll({item['key']: item['value']}));
        obj[deviceId] = deviceMap;
      } else {
        res['keyValues'].forEach(
            (item) => {obj.putIfAbsent(item['key'], () => item['value'])});
      }
      datas.addEntries(obj.entries);
      controller.add(datas);
    }
  }

  Future close() async {
    UseSocket.getInstance()?.close();
    UseSocket.getInstance()
        ?.removeReceivedMessageCallback(dealtMeesageCallback);

    await controller.close();
  }

  Future closeListen() async {
    /// 取消服务端的数据推送
    if (eventType != null) {
      start(idList, false, type: eventType!);
    }
    UseSocket.getInstance()
        ?.removeReceivedMessageCallback(dealtMeesageCallback);

    await controller.close();
  }
}
